import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.olap4j.OlapConnection;
import org.olap4j.OlapWrapper;
import org.olap4j.PreparedOlapStatement;
import org.olap4j.driver.xmla.XmlaOlap4jMeasure;
import org.olap4j.metadata.Cube;
import org.olap4j.metadata.Dimension;
import org.olap4j.metadata.Hierarchy;
import org.olap4j.metadata.Level;
import org.olap4j.metadata.Measure;
import org.olap4j.metadata.NamedList;

public class GetCubeMetaJson {

	// public static String URL = ""
	public static final String URL = "jdbc:xmla:Server=http://10.20.14.40:9999/olap/msmdpump.dll;Catalog=\"烟草数据中心\"";
	public static final String USER = "\"datacenter\\\\yangchen\"";
	public static final String PASSWORD = "\"Neu_sdyc\"";
	public static final String HAS_CHILDREN_NODE_MOULD = "{\"text\" : \"@text\",\"cls\" :  \"folder\",\"leaf\" : false,\"allowDrag\" : false,\"children\" : [";
	public static final String CHILDREN_NODE_MOULD = "{\"text\" : \"@text\",\"id\" : \"@uniquename\",\"leaf\" : true}";
	public static final String DIMENSION_HAS_CHILDREN_NODE_MOULD = "{\"text\" : \"@text\",\"id\" : \"@uniquename\",\"cls\" :  \"folder\",\"leaf\" : false,\"allowDrag\" : false,\"children\" : [";

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws SQLException,
			ClassNotFoundException {
		Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");

		OlapConnection con = (OlapConnection) DriverManager.getConnection(URL,
				USER, PASSWORD);
		OlapWrapper wrapper = (OlapWrapper) con;
		OlapConnection olapConnection = (OlapConnection) wrapper
				.unwrap(OlapConnection.class);
		String sql = " select from [卷烟经营]";
		PreparedOlapStatement postmt = olapConnection.prepareOlapStatement(sql);
		Cube cube = postmt.getCube();
		NamedList<Dimension> dimensions = cube.getDimensions();
		List<Measure> measures = cube.getMeasures();
		Collections.sort(measures, new Comparator<Object>() {
			public int compare(Object object1, Object object2) {
				XmlaOlap4jMeasure measure1 = (XmlaOlap4jMeasure) object1;
				XmlaOlap4jMeasure measure2 = (XmlaOlap4jMeasure) object2;
				int groupNameOrder = measure1.getGroupName().compareTo(
						measure2.getGroupName());
				if (0 < groupNameOrder) {
					return 1;
				} else if (0 > groupNameOrder) {
					return -1;
				} else {
					int displayOrder = measure1.getDisplayFolder().compareTo(
							measure2.getDisplayFolder());
					if (0 < displayOrder) {
						return 1;
					} else if (0 > displayOrder) {
						return -1;
					} else {
						return measure1.getUniqueName().compareTo(
								measure2.getUniqueName());
					}
				}
			}
		});

		StringBuffer buffer = new StringBuffer("[");
		Map groupNames = new LinkedHashMap();
		Map displayFolders = new LinkedHashMap();
		Map uniqueNames = new LinkedHashMap();
		Map captions = new LinkedHashMap();
		// 将measures存入四个Map中
		for (int i = 0; i < measures.size(); i++) {
			XmlaOlap4jMeasure measure = (XmlaOlap4jMeasure) measures.get(i);
			String caption = measure.getCaption();
			String groupName = measure.getGroupName();
			String displayFolder = measure.getDisplayFolder();
			String uniqueName = measure.getUniqueName();
			groupNames.put(groupName, groupName);
			displayFolders.put("".equals(displayFolder.trim()) ? groupName
					+ "null" : groupName + displayFolder, displayFolder);
			uniqueNames.put("".equals(displayFolder.trim()) ? groupName
					+ "null" + uniqueName : groupName + displayFolder
					+ uniqueName, uniqueName);
			captions.put(uniqueName, caption);
		}
		// 获取树形结构的Map
		Map newgroupNames = getMapForTree(groupNames, displayFolders,
				uniqueNames);
		buffer.append(getMeasuresForTree(newgroupNames, captions));
		buffer.append("},");
		buffer.append(getDimensionsForTree(dimensions));
		buffer.append("]");
		System.out.println(buffer.toString());
	}

	/**
	 * 生成树形结构Map
	 * 
	 * @param groupNames
	 * @param displayFolders
	 * @param uniqueNames
	 * @return Map
	 */
	@SuppressWarnings("unchecked")
	private static Map getMapForTree(Map groupNames, Map displayFolders,
			Map uniqueNames) {
		Map newgroupNames = new LinkedHashMap();
		Map newdisplayFolders = new LinkedHashMap();
		Map newuniqueNames = new LinkedHashMap();
		Iterator<String> groupKeyItor = groupNames.keySet().iterator();
		while (groupKeyItor.hasNext()) {
			String groupkey = groupKeyItor.next();
			Iterator<String> folderKeyItor = displayFolders.keySet().iterator();
			newdisplayFolders = new LinkedHashMap();
			while (folderKeyItor.hasNext()) {
				String folderkey = folderKeyItor.next();
				if (folderkey.startsWith(groupkey)) {
					Iterator<String> uniqueKeyItor = uniqueNames.keySet()
							.iterator();
					newuniqueNames = new LinkedHashMap();
					while (uniqueKeyItor.hasNext()) {
						String uniquekey = uniqueKeyItor.next();
						if (uniquekey.startsWith(folderkey)) {
							newuniqueNames.put(uniquekey,
									uniqueNames.get(uniquekey));
						} else {
							continue;
						}
					}
					newdisplayFolders.put(folderkey, newuniqueNames);
				}
			}
			newgroupNames.put(groupkey, newdisplayFolders);
		}
		return newgroupNames;
	}

	/**
	 * 获取度量信息的树形结构
	 * 
	 * @param newgroupNames
	 * @param captions
	 * @return String
	 */
	@SuppressWarnings("unchecked")
	private static String getMeasuresForTree(Map newgroupNames, Map captions) {
		StringBuffer buffer = new StringBuffer();
		Iterator<String> itor_group = newgroupNames.keySet().iterator();
		boolean flag1 = true;
		while (itor_group.hasNext()) {
			if (!flag1) {
				buffer.append("},");
			} else {
				flag1 = false;
			}
			String groupkey = itor_group.next();
			buffer.append(HAS_CHILDREN_NODE_MOULD.replace("@text", "∑ "
					+ groupkey));
			Map folder = (Map) newgroupNames.get(groupkey);
			Iterator<String> itor_folder = folder.keySet().iterator();
			boolean flag2 = true;
			while (itor_folder.hasNext()) {
				String folderkey = itor_folder.next();
				Map unique = (Map) folder.get(folderkey);
				if (folderkey.endsWith("null")) {
					if (!flag2) {
						buffer.append(",");
					} else {
						flag2 = false;
					}
					Iterator<String> itor_unique = unique.keySet().iterator();
					boolean flag3 = true;
					while (itor_unique.hasNext()) {
						if (!flag3) {
							buffer.append(",");
						} else {
							flag3 = false;
						}
						String uniquekey = itor_unique.next();
						String uniquename = (String) unique.get(uniquekey);
						String caption = (String) captions.get(uniquename);
						buffer.append(CHILDREN_NODE_MOULD.replace("@text",
								caption).replace("@uniquename", uniquename));
					}
				} else {
					if (!flag2) {
						buffer.append(",");
					} else {
						flag2 = false;
					}
					Iterator<String> itor_unique = unique.keySet().iterator();
					String displayFolder = folderkey.substring(groupkey
							.length());
					buffer.append(HAS_CHILDREN_NODE_MOULD.replace("@text",
							displayFolder));
					boolean flag3 = true;
					while (itor_unique.hasNext()) {
						if (!flag3) {
							buffer.append(",");
						} else {
							flag3 = false;
						}
						String uniquekey = itor_unique.next();
						String uniquename = (String) unique.get(uniquekey);
						String caption = (String) captions.get(uniquename);
						buffer.append(CHILDREN_NODE_MOULD.replace("@text",
								caption).replace("@uniquename", uniquename));
					}
					buffer.append("]}");
				}
			}
			buffer.append("]");
		}
		return buffer.toString();
	}

	/**
	 * 获取维度信息的树形结构
	 * 
	 * @param dimensions
	 * @return String
	 */
	private static String getDimensionsForTree(NamedList<Dimension> dimensions) {
		StringBuffer buffer = new StringBuffer();
		boolean flag = true;
		for (int i = 0; i < dimensions.size(); i++) {
			Dimension dimension = dimensions.get(i);
			String caption = dimension.getCaption();
			if ("Measures".equals(caption)) {
				continue;
			}
			buffer.append(flag ? "" : ",").append(
					HAS_CHILDREN_NODE_MOULD.replace("@text", caption));
			flag = false;
			NamedList<Hierarchy> hierarchies = dimension.getHierarchies();
			for (int j = 0; j < hierarchies.size(); j++) {
				Hierarchy hierarchie = hierarchies.get(j);
				String caption2 = hierarchie.getCaption();
				String uniqueName2 = hierarchie.getUniqueName();
				buffer.append(0 == j ? "" : ",").append(
						DIMENSION_HAS_CHILDREN_NODE_MOULD.replace("@text",
								caption2).replace("@uniquename", uniqueName2));
				NamedList<Level> levels = hierarchie.getLevels();
				// 去掉all，从1开始
				for (int k = 1; k < levels.size(); k++) {
					Level level = levels.get(k);
					String caption3 = level.getCaption();
					String uniqueName3 = level.getUniqueName();
					buffer.append(1 == k ? "" : ",").append(
							CHILDREN_NODE_MOULD.replace("@text", caption3)
									.replace("@uniquename", uniqueName3));
				}
				buffer.append("]}");
			}
			buffer.append("]}");
		}
		return buffer.toString();
	}
}
